/*
 * Contacts.java
 *
 * Created on May 23, 2008, 6:35 PM
 */
package org.potomak.patientmanager.gui;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Set;
import java.util.Arrays;
import java.util.Date;
import java.lang.Double;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.event.TableModelEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.ListModel;
import javax.swing.table.TableModel;
import javax.swing.ComboBoxModel;
import javax.swing.table.AbstractTableModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.DefaultComboBoxModel;
import javax.swing.AbstractListModel;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JWindow;
import javax.swing.JFrame;
import javax.swing.JDialog;
import javax.swing.DefaultListSelectionModel;
import javax.swing.JTable;
import javax.swing.event.TableModelListener;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import javax.jdo.Transaction;
import javax.jdo.JDOHelper;

import com.apple.mrj.MRJAboutHandler;
import com.apple.mrj.MRJPrefsHandler;
import com.apple.mrj.MRJQuitHandler;

import org.potomak.patientmanager.beans.model.PatientBean;
import org.potomak.patientmanager.beans.model.CheckUpBean;
import org.potomak.patientmanager.persistence.JPoxJDO;
import org.potomak.patientmanager.tools.BMICalculator;
import org.potomak.patientmanager.ContactsProperties;

/**
 *
 * @author  mobile
 */
public class Contacts extends javax.swing.JFrame implements MRJAboutHandler, MRJQuitHandler, MRJPrefsHandler {

    private JPoxJDO jpoxJDO;
    private PatientBean[] patients;
    private int selectedPatientIndex;
    private int selectedCheckUpIndex;
    private ListModel patientListModel;
    private TableModel checkUpsTableModel;
    private ComboBoxModel genderListModel;
    private boolean patientInfoEditable = false;
    private boolean notesEditable = false;
    
    // FIXME
    //private JMenu menu = new JMenu("menu");
    //private JMenuBar menuBar = new JMenuBar();
    //private JMenuItem menuItem = new JMenuItem("test");

    class PatientsListModel extends DefaultComboBoxModel {

        public PatientsListModel(Object[] data) {
            super(data);
        }
    }

    class CheckUpsTableModel extends DefaultTableModel {

        public CheckUpsTableModel() {
            super(new Object[][]{}, new String[]{"Date", "Weight"});
        }

        public boolean isCellEditable(int row, int column) {
            return true;
        }

        public void setDataVector(Set checkUps) {
            Object[] checkUpsArray = checkUps.toArray();
            
            // sorting check ups
            Arrays.sort(checkUpsArray, new CheckUpsComparator());
            
            Object[][] checkUpsDataVector = new Object[checkUpsArray.length][];
            for (int i = 0; i < checkUpsArray.length; i++) {
                checkUpsDataVector[i] = new Object[2];
                checkUpsDataVector[i][0] = ContactsProperties.contactsDateFormat.format(((CheckUpBean) checkUpsArray[i]).getDate());
                checkUpsDataVector[i][1] = ((CheckUpBean) checkUpsArray[i]).getWeight();
            }

            super.setDataVector(checkUpsDataVector, new String[]{"Date", "Weight"});
        }
    }

    /** Creates new form Contacts */
    public Contacts() {
        // FIXME
        //menu.add(menuItem);
        //menuBar.add(menu);
        //this.setJMenuBar(menuBar);
        System.out.println("getJMenuBar --> "+this.getJMenuBar());

        JDialog passwordWindow = new PasswordDialog(this);
        passwordWindow.setVisible(true);

        patientListModel = new PatientsListModel(new Object[]{});

        genderListModel = new GenderComboBoxModel();

        checkUpsTableModel = new CheckUpsTableModel();

        initComponents();

        checkUpsTable.getSelectionModel().addListSelectionListener(
                new ListSelectionListener() {

                    public void valueChanged(ListSelectionEvent event) {
                        checkUpsListValueChanged(event);
                    }
                });
    }

    public void handleAbout() {
        JOptionPane.showMessageDialog(null,
                "about",
                "about",
                JOptionPane.INFORMATION_MESSAGE);
    }

    public void handlePrefs() throws IllegalStateException {
        JOptionPane.showMessageDialog(null,
                "prefs",
                "prefs",
                JOptionPane.INFORMATION_MESSAGE);
    }

    public void handleQuit() throws IllegalStateException {
        // handle exit here
        System.exit(0);
    }

    public PatientBean[] getPatients() {
        return this.patients;
    }

    public PatientBean getSelectedPatient() {
        return this.patients[selectedPatientIndex];
    }

    public void setJpoxJDO(JPoxJDO jpoxJDO) {
        this.jpoxJDO = jpoxJDO;
    }

    private void setPatientListData(PatientBean[] patients) {
        ListItem[] rows = new ListItem[patients.length];
        for (int i = 0; i < patients.length; i++) {
            rows[i] = new ListItem(patients[i].getId(), patients[i].getName() + " (" + ContactsProperties.contactsDateFormat.format(patients[i].getBirthDay()) + ")");
        }

        Arrays.sort(rows, new ListItemComparator());

        patientList.setModel(new PatientsListModel(rows));
    }

    public void updatePatientListData() {
        this.patients = jpoxJDO.patientList();
        setPatientListData(this.patients);
    }

    private void setCheckUpsTableData(Set checkUps) {
        ((CheckUpsTableModel) checkUpsTable.getModel()).setDataVector(checkUps);
    }

    public void updateCheckUpsTableData() {
        setCheckUpsTableData(getSelectedPatient().getCheckUps());
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        tabsPanel = new javax.swing.JTabbedPane();
        notesTab = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        notesTextArea = new javax.swing.JTextArea();
        cancelNotesButton = new javax.swing.JButton();
        modifySaveNotesButton = new javax.swing.JButton();
        checkUpsTab = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        checkUpsTable = new javax.swing.JTable();
        showChartButton = new javax.swing.JButton();
        removeCheckUpButton = new javax.swing.JButton();
        addCheckUpButton = new javax.swing.JButton();
        BMIConstLabel = new javax.swing.JLabel();
        textStepLabel = new javax.swing.JLabel();
        stepLabel = new javax.swing.JLabel();
        BMILabel = new javax.swing.JLabel();
        patientInfoTab = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        heightLabel = new javax.swing.JLabel();
        birthDayLabel = new javax.swing.JLabel();
        genderLabel = new javax.swing.JLabel();
        nameLabel = new javax.swing.JLabel();
        genderField = new javax.swing.JComboBox();
        nameField = new javax.swing.JTextField();
        birthDayField = new javax.swing.JTextField();
        heightField = new javax.swing.JTextField();
        dateLabel = new javax.swing.JLabel();
        dateField = new javax.swing.JLabel();
        modifySavePatientButton = new javax.swing.JButton();
        cancelPatientButton = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        patientList = new javax.swing.JList();
        addPatientButton = new javax.swing.JButton();
        removePatientButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Contacts");
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        tabsPanel.setRequestFocusEnabled(false);

        notesTextArea.setColumns(20);
        notesTextArea.setRows(5);
        notesTextArea.setEnabled(false);
        jScrollPane3.setViewportView(notesTextArea);

        cancelNotesButton.setText("Cancel");
        cancelNotesButton.setEnabled(false);
        cancelNotesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelNotesButtonActionPerformed(evt);
            }
        });

        modifySaveNotesButton.setText("Modify");
        modifySaveNotesButton.setEnabled(false);
        modifySaveNotesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                modifySaveNotesButtonActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout notesTabLayout = new org.jdesktop.layout.GroupLayout(notesTab);
        notesTab.setLayout(notesTabLayout);
        notesTabLayout.setHorizontalGroup(
            notesTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, notesTabLayout.createSequentialGroup()
                .addContainerGap()
                .add(notesTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(notesTabLayout.createSequentialGroup()
                        .add(cancelNotesButton)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(modifySaveNotesButton))
                    .add(jScrollPane3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 587, Short.MAX_VALUE))
                .addContainerGap())
        );
        notesTabLayout.setVerticalGroup(
            notesTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(notesTabLayout.createSequentialGroup()
                .addContainerGap()
                .add(jScrollPane3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 313, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 32, Short.MAX_VALUE)
                .add(notesTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(modifySaveNotesButton)
                    .add(cancelNotesButton))
                .addContainerGap())
        );

        tabsPanel.addTab("Notes", notesTab);

        checkUpsTable.setModel(checkUpsTableModel);
        checkUpsTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jScrollPane2.setViewportView(checkUpsTable);

        showChartButton.setText("Show chart");
        showChartButton.setEnabled(false);
        showChartButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                showChartButtonActionPerformed(evt);
            }
        });

        removeCheckUpButton.setText("Remove");
        removeCheckUpButton.setEnabled(false);
        removeCheckUpButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeCheckUpButtonActionPerformed(evt);
            }
        });

        addCheckUpButton.setText("Add");
        addCheckUpButton.setEnabled(false);
        addCheckUpButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addCheckUpButtonActionPerformed(evt);
            }
        });

        BMIConstLabel.setFont(new java.awt.Font("Lucida Grande", 0, 24)); // NOI18N
        BMIConstLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        BMIConstLabel.setText("BMI: ");

        textStepLabel.setFont(new java.awt.Font("Lucida Grande", 0, 24)); // NOI18N
        textStepLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        textStepLabel.setText("Reached:");
        textStepLabel.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);

        stepLabel.setFont(new java.awt.Font("Lucida Grande", 0, 24)); // NOI18N
        stepLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        stepLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP);

        BMILabel.setFont(new java.awt.Font("Lucida Grande", 0, 24)); // NOI18N
        BMILabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);

        org.jdesktop.layout.GroupLayout checkUpsTabLayout = new org.jdesktop.layout.GroupLayout(checkUpsTab);
        checkUpsTab.setLayout(checkUpsTabLayout);
        checkUpsTabLayout.setHorizontalGroup(
            checkUpsTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, checkUpsTabLayout.createSequentialGroup()
                .addContainerGap()
                .add(checkUpsTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(checkUpsTabLayout.createSequentialGroup()
                        .add(checkUpsTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(checkUpsTabLayout.createSequentialGroup()
                                .add(BMIConstLabel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 124, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                .add(14, 14, 14)
                                .add(BMILabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 116, Short.MAX_VALUE))
                            .add(stepLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 254, Short.MAX_VALUE)
                            .add(textStepLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 254, Short.MAX_VALUE))
                        .add(18, 18, 18)
                        .add(jScrollPane2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 315, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                    .add(checkUpsTabLayout.createSequentialGroup()
                        .add(addCheckUpButton)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(removeCheckUpButton)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(showChartButton)))
                .addContainerGap())
        );
        checkUpsTabLayout.setVerticalGroup(
            checkUpsTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(checkUpsTabLayout.createSequentialGroup()
                .addContainerGap()
                .add(checkUpsTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(checkUpsTabLayout.createSequentialGroup()
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 78, Short.MAX_VALUE)
                        .add(checkUpsTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false)
                            .add(BMILabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .add(BMIConstLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .add(82, 82, 82)
                        .add(textStepLabel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 65, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(stepLabel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 50, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                    .add(jScrollPane2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 313, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 32, Short.MAX_VALUE)
                .add(checkUpsTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(showChartButton)
                    .add(removeCheckUpButton)
                    .add(addCheckUpButton))
                .addContainerGap())
        );

        tabsPanel.addTab("Check ups", checkUpsTab);

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Contact info"));

        heightLabel.setText("Height");

        birthDayLabel.setText("Date of birth");

        genderLabel.setText("Gender");

        nameLabel.setText("Name");

        genderField.setModel(genderListModel);
        genderField.setEnabled(false);

        nameField.setEnabled(false);

        birthDayField.setEnabled(false);

        heightField.setEnabled(false);

        dateLabel.setText("Added");

        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jPanel1Layout.createSequentialGroup()
                        .add(nameLabel)
                        .add(115, 115, 115)
                        .add(nameField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 242, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap(162, Short.MAX_VALUE))
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
                        .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                            .add(org.jdesktop.layout.GroupLayout.LEADING, jPanel1Layout.createSequentialGroup()
                                .add(heightLabel)
                                .add(109, 109, 109)
                                .add(heightField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 121, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                            .add(org.jdesktop.layout.GroupLayout.LEADING, jPanel1Layout.createSequentialGroup()
                                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                    .add(genderLabel)
                                    .add(birthDayLabel))
                                .add(71, 71, 71)
                                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                    .add(birthDayField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 121, Short.MAX_VALUE)
                                    .add(genderField, 0, 121, Short.MAX_VALUE))))
                        .add(283, 283, 283))
                    .add(jPanel1Layout.createSequentialGroup()
                        .add(dateLabel)
                        .add(18, 18, 18)
                        .add(dateField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 86, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap())))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(nameLabel)
                    .add(nameField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(genderLabel)
                    .add(genderField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(birthDayLabel)
                    .add(birthDayField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(10, 10, 10)
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(heightLabel)
                    .add(heightField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(36, 36, 36)
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false)
                    .add(dateField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(dateLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap(78, Short.MAX_VALUE))
        );

        modifySavePatientButton.setText("Modify");
        modifySavePatientButton.setEnabled(false);
        modifySavePatientButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                modifySavePatientButtonActionPerformed(evt);
            }
        });

        cancelPatientButton.setText("Cancel");
        cancelPatientButton.setEnabled(false);
        cancelPatientButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelPatientButtonActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout patientInfoTabLayout = new org.jdesktop.layout.GroupLayout(patientInfoTab);
        patientInfoTab.setLayout(patientInfoTabLayout);
        patientInfoTabLayout.setHorizontalGroup(
            patientInfoTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, patientInfoTabLayout.createSequentialGroup()
                .addContainerGap()
                .add(patientInfoTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(patientInfoTabLayout.createSequentialGroup()
                        .add(cancelPatientButton)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(modifySavePatientButton))
                    .add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        patientInfoTabLayout.setVerticalGroup(
            patientInfoTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(patientInfoTabLayout.createSequentialGroup()
                .addContainerGap()
                .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 50, Short.MAX_VALUE)
                .add(patientInfoTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(modifySavePatientButton)
                    .add(cancelPatientButton))
                .addContainerGap())
        );

        tabsPanel.addTab("Info", patientInfoTab);

        patientList.setFont(new java.awt.Font("Lucida Grande", 0, 14));
        patientList.setModel(patientListModel);
        patientList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        patientList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                patientListValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(patientList);

        addPatientButton.setText("Add");
        addPatientButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addPatientButtonActionPerformed(evt);
            }
        });

        removePatientButton.setText("Remove");
        removePatientButton.setEnabled(false);
        removePatientButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removePatientButtonActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                        .add(addPatientButton)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(removePatientButton))
                    .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 247, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(18, 18, 18)
                .add(tabsPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 648, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                        .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 410, Short.MAX_VALUE)
                        .add(18, 18, 18)
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                            .add(removePatientButton)
                            .add(addPatientButton)))
                    .add(tabsPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 457, Short.MAX_VALUE))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void enableUniqueTab(int index) {
        // total number of tabs
        // TODO: find a way to get the number of tabs
        int totTabs = 3;
        for (int i = 0; i < totTabs; i++) {
            // disable this tab
            if (i != index) {
                tabsPanel.setEnabledAt(i, false);
            }
        }
    }

    private void enableAllTabs() {
        // total number of tabs
        // TODO: find a way to get the number of tabs
        int totTabs = 3;
        for (int i = 0; i < totTabs; i++) {
            tabsPanel.setEnabledAt(i, true);
        }
    }

    private void setEnabledContactsList(boolean enabled) {
        patientList.setEnabled(enabled);
        addPatientButton.setEnabled(enabled);
        removePatientButton.setEnabled(enabled);
    }

    private void setPatientInfoEditable(boolean isEditable) {
        if (isEditable) {
            setEnabledContactsList(false);
            enableUniqueTab(2);
            cancelPatientButton.setEnabled(true);
            nameField.setEnabled(true);
            genderField.setEnabled(true);
            birthDayField.setEnabled(true);
            heightField.setEnabled(true);
            modifySavePatientButton.setText("Save");
            getRootPane().setDefaultButton(modifySavePatientButton);
        } else {
            setEnabledContactsList(true);
            enableAllTabs();
            cancelPatientButton.setEnabled(false);
            nameField.setEnabled(false);
            genderField.setEnabled(false);
            birthDayField.setEnabled(false);
            heightField.setEnabled(false);
            modifySavePatientButton.setText("Modify");
            getRootPane().setDefaultButton(null);
        }
    }

    private void setNotesEditable(boolean isEditable) {
        if (isEditable) {
            setEnabledContactsList(false);
            enableUniqueTab(0);
            cancelNotesButton.setEnabled(true);
            notesTextArea.setEnabled(true);
            modifySaveNotesButton.setText("Save");
            getRootPane().setDefaultButton(modifySaveNotesButton);
        } else {
            setEnabledContactsList(true);
            enableAllTabs();
            cancelNotesButton.setEnabled(false);
            notesTextArea.setEnabled(false);
            modifySaveNotesButton.setText("Modify");
            getRootPane().setDefaultButton(null);
        }
    }

private void modifySavePatientButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_modifySavePatientButtonActionPerformed
    if (!patientInfoEditable) {
        patientInfoEditable = true;
        setPatientInfoEditable(true);
    } else {
        //default icon, custom title
        int wantSave = JOptionPane.showConfirmDialog(this, "Do you want to save changes made?", "Save", JOptionPane.YES_NO_OPTION);
        System.out.println("Confirm save contact info dialog result: " + wantSave);

        if (wantSave == 0) {
            String name = nameField.getText().trim();
            Date birthday = null;
            try {
                birthday = ContactsProperties.contactsDateFormat.parse(birthDayField.getText());
            } catch (Exception e) {
                e.printStackTrace();
            // TODO visualizza messaggio di errore
            }
            String gender = ((ListItem) genderField.getModel().getSelectedItem()).getKey().toString().trim();
            Double height = new Double(heightField.getText());

            boolean success = jpoxJDO.updatePatient(getSelectedPatient(), name, birthday, gender, height);

            if (!success) {
                JOptionPane.showMessageDialog(this, "Contact info not saved.", "Error", JOptionPane.ERROR_MESSAGE);
            }
            updatePatientListData();
            patientInfoEditable = false;
            setPatientInfoEditable(false);
        }
    }
}//GEN-LAST:event_modifySavePatientButtonActionPerformed

private void cancelPatientButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelPatientButtonActionPerformed
    patientInfoEditable = false;
    setPatientInfoEditable(false);
}//GEN-LAST:event_cancelPatientButtonActionPerformed

private void patientListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_patientListValueChanged
    if (evt.getValueIsAdjusting()) {
        ListItem selectedItem = (ListItem) ((javax.swing.JList) evt.getSource()).getSelectedValue();
        if (selectedItem != null) {
            if (!modifySavePatientButton.isEnabled()) {
                modifySavePatientButton.setEnabled(true);
            }
            if (!modifySaveNotesButton.isEnabled()) {
                modifySaveNotesButton.setEnabled(true);
            }
            if (!showChartButton.isEnabled()) {
                showChartButton.setEnabled(true);
            }
            if (!addCheckUpButton.isEnabled()) {
                addCheckUpButton.setEnabled(true);
            }
            removePatientButton.setEnabled(true);
            int i;
            for (i = 0; i < patients.length && patients[i].getId() != (Integer) (selectedItem.getKey()); i++);
            selectedPatientIndex = i;
            nameField.setText(patients[i].getName());
            ListItem genderItem;
            if (patients[i].getGender().equals("M")) {
                genderItem = new ListItem("M", "Male");
            } else {
                genderItem = new ListItem("F", "Female");
            }
            genderField.getModel().setSelectedItem(genderItem);
            birthDayField.setText(ContactsProperties.contactsDateFormat.format(patients[i].getBirthDay()));
            heightField.setText(patients[i].getHeight().toString());
            dateField.setText(ContactsProperties.contactsDateFormat.format(patients[i].getDate()));
            
            ((CheckUpsTableModel) checkUpsTableModel).setDataVector(patients[i].getCheckUps());
            
            notesTextArea.setText(patients[i].getNotes());
            
            Object[] checkUps = patients[i].getCheckUps().toArray();
            Double BMI = 0.0;
            int step = 0;        
            if(checkUps.length > 0) {
                Arrays.sort(checkUps, new CheckUpsComparator());

                Double lastWeight = ((CheckUpBean)checkUps[checkUps.length-1]).getWeight();
                Double firstWeight = ((CheckUpBean)checkUps[0]).getWeight();

                BMI = BMICalculator.calculate(lastWeight, patients[i].getHeight());

                step = (int)(firstWeight-lastWeight)/ContactsProperties.step;
                if(step < 0) {
                    step = 0;
                }
            }
            
            BMILabel.setText(BMI.toString());
            stepLabel.setText(step+" step");
        } else {
            addPatientButton.setEnabled(false);
            removePatientButton.setEnabled(false);
        }
    }
}//GEN-LAST:event_patientListValueChanged

private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
    System.out.println("Shutting down JPOX persistence manager.");
    jpoxJDO.shutdown();
    System.out.println("***********************************************************");
    System.exit(0);
}//GEN-LAST:event_formWindowClosing

private void cancelNotesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelNotesButtonActionPerformed
    notesEditable = false;
    setNotesEditable(false);
}//GEN-LAST:event_cancelNotesButtonActionPerformed

private void modifySaveNotesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_modifySaveNotesButtonActionPerformed
    if (!notesEditable) {
        notesEditable = true;
        setNotesEditable(true);
    } else {
        int wantSave = JOptionPane.showConfirmDialog(this, "Do you want to save changes made?", "Save", JOptionPane.YES_NO_OPTION);
        System.out.println("Confirm save notes dialog result: " + wantSave);

        if (wantSave == 0) {
            String notes = notesTextArea.getText().trim();

            boolean success = jpoxJDO.updateNotes(getSelectedPatient(), notes);

            if (!success) {
                JOptionPane.showMessageDialog(this, "Notes not saved.", "Error", JOptionPane.ERROR_MESSAGE);
            }

            notesEditable = false;
            setNotesEditable(false);
        }
    }
}//GEN-LAST:event_modifySaveNotesButtonActionPerformed

private void showChartButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showChartButtonActionPerformed
    Object[] checkUps = getSelectedPatient().getCheckUps().toArray();

    Arrays.sort(checkUps, new CheckUpsComparator());

    CheckUpBean[] castedArray = new CheckUpBean[checkUps.length];
    for (int i = 0; i < checkUps.length; i++) {
        castedArray[i] = (CheckUpBean) checkUps[i];
    }

    ChartDialog chartWindow = new ChartDialog(this, castedArray, getSelectedPatient().getHeight());
    chartWindow.setSize(640, 480);
    chartWindow.validate();
    chartWindow.setVisible(true);
    chartWindow.refresh();
}//GEN-LAST:event_showChartButtonActionPerformed

private void addPatientButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addPatientButtonActionPerformed
    JDialog addPatientWindow = new NewPatientDialog(this, this.jpoxJDO);
    addPatientWindow.setVisible(true);
}//GEN-LAST:event_addPatientButtonActionPerformed

private void removePatientButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removePatientButtonActionPerformed

    String patientName = getSelectedPatient().getName();

    int wantRemove = JOptionPane.showConfirmDialog(this, "Do you want to remove contact " + patientName + "?", "Remove", JOptionPane.YES_NO_OPTION);
    System.out.println("Confirm remove patient dialog result: " + wantRemove);

    if (wantRemove == 0) {
        boolean success = jpoxJDO.removePatient(getSelectedPatient());

        if (success) {
            modifySavePatientButton.setEnabled(false);
            modifySaveNotesButton.setEnabled(false);
            showChartButton.setEnabled(false);
            addCheckUpButton.setEnabled(false);
            removeCheckUpButton.setEnabled(false);
            removePatientButton.setEnabled(false);
        } else {
            JOptionPane.showMessageDialog(this, "Error removing contact.", "Error", JOptionPane.ERROR_MESSAGE);
        }

        updatePatientListData();
    }
}//GEN-LAST:event_removePatientButtonActionPerformed

private void addCheckUpButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addCheckUpButtonActionPerformed
    JDialog addCheckUpWindow = new NewCheckUpDialog(this, jpoxJDO);
    addCheckUpWindow.setVisible(true);
}//GEN-LAST:event_addCheckUpButtonActionPerformed

    private void checkUpsListValueChanged(javax.swing.event.ListSelectionEvent evt) {
        if (evt.getValueIsAdjusting()) {
            selectedCheckUpIndex = ((DefaultListSelectionModel) evt.getSource()).getLeadSelectionIndex();
            if (selectedCheckUpIndex != -1) {
                removeCheckUpButton.setEnabled(true);
            } else {
                removeCheckUpButton.setEnabled(false);
            }
            System.out.println("selected row: " + selectedCheckUpIndex);
        }
    }

private void removeCheckUpButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeCheckUpButtonActionPerformed
    int wantRemove = JOptionPane.showConfirmDialog(this, "Do you want to remove check up?", "Remove", JOptionPane.YES_NO_OPTION);

    if (wantRemove == 0) {
        CheckUpBean checkUpBean = new CheckUpBean();
        try {
            checkUpBean.setDate(ContactsProperties.contactsDateFormat.parse((String) checkUpsTable.getModel().getValueAt(selectedCheckUpIndex, 0)));
        } catch (ParseException ex) {
            Logger.getLogger(Contacts.class.getName()).log(Level.SEVERE, null, ex);
        }
        checkUpBean.setWeight((Double) checkUpsTable.getModel().getValueAt(selectedCheckUpIndex, 1));
        checkUpBean.setPatient(getSelectedPatient());

        boolean success = jpoxJDO.removeCheckUp(getSelectedPatient(), checkUpBean);

        if (success) {
            removeCheckUpButton.setEnabled(false);
        } else {
            JOptionPane.showMessageDialog(this, "Error removing check up.", "Error", JOptionPane.ERROR_MESSAGE);
        }

        updateCheckUpsTableData();
    }
}//GEN-LAST:event_removeCheckUpButtonActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel BMIConstLabel;
    private javax.swing.JLabel BMILabel;
    private javax.swing.JButton addCheckUpButton;
    private javax.swing.JButton addPatientButton;
    private javax.swing.JTextField birthDayField;
    private javax.swing.JLabel birthDayLabel;
    private javax.swing.JButton cancelNotesButton;
    private javax.swing.JButton cancelPatientButton;
    private javax.swing.JPanel checkUpsTab;
    private javax.swing.JTable checkUpsTable;
    private javax.swing.JLabel dateField;
    private javax.swing.JLabel dateLabel;
    private javax.swing.JComboBox genderField;
    private javax.swing.JLabel genderLabel;
    private javax.swing.JTextField heightField;
    private javax.swing.JLabel heightLabel;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JButton modifySaveNotesButton;
    private javax.swing.JButton modifySavePatientButton;
    private javax.swing.JTextField nameField;
    private javax.swing.JLabel nameLabel;
    private javax.swing.JPanel notesTab;
    private javax.swing.JTextArea notesTextArea;
    private javax.swing.JPanel patientInfoTab;
    private javax.swing.JList patientList;
    private javax.swing.JButton removeCheckUpButton;
    private javax.swing.JButton removePatientButton;
    private javax.swing.JButton showChartButton;
    private javax.swing.JLabel stepLabel;
    private javax.swing.JTabbedPane tabsPanel;
    private javax.swing.JLabel textStepLabel;
    // End of variables declaration//GEN-END:variables
}
